home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / VideoToolbox 97.08.16 / (Utilities) / ReadLuminanceMeter / LuminanceMeter.c next >
Encoding:
C/C++ Source or Header  |  1997-02-26  |  10.2 KB  |  362 lines  |  [TEXT/CWIE]

  1. /* luminanceMeter.c
  2.  
  3.      Macintosh c-routines that can be used to read out the Minolta LS-110/100 luminance meters
  4.      using the RS-232 output.
  5.     
  6.     Please send suggestions, bugs, improvements, comments to f.w.cornelissen@med.rug.nl    
  7.     Further details in read me file. Use at your own risk.
  8.  
  9. Your program needs to open a serial port using "initLuminanceMeter(PORT)". Set PORT to the port to 
  10. which you connected your meter to (either the printer or modem port) using the
  11. #define PORT PRINTER_PORT/MODEM_PORT statement.
  12.  
  13. You can then read the luminance values using "getLuminance()". Get luminance takes a pointer to a double (lum)
  14. in which to store the luminance value, and a pointer to a string (message) to store the other stuff in the
  15. luminance meter outputs. You don't really need this info to make measurements.
  16.  
  17. Once you're finished with measuring you should close the connection using "endLuminanceMeter( )". That's all.
  18.  
  19. There's a convenience routine "returnPortName()" that you can use to print out the port for which the
  20. program is configured.
  21.  
  22. Make sure you put    #include "luminanceMeter.h" into your code.
  23.  
  24.  
  25. program example
  26.  
  27.     #include "luminanceMeter.h"
  28.  
  29.     void main( void )
  30.     {
  31.         int i;
  32.         double lum;
  33.         char message[255];
  34.         
  35.         initLuminanceMeter( MODEM_PORT );
  36.         
  37.         printf( "\nMeasuring luminance\n" );
  38.         for( i = 0; i < 10; i ++ )
  39.         {
  40.             getLuminance( &lum, message );
  41.             printf( "Measurement: %d, Luminance: %f, message: %s\n", i, luminance, message );
  42.         }
  43.         
  44.         endLuminanceMeter();
  45.     }
  46.     
  47. ************************************************************************
  48.  
  49.     27-06-92     FWC     created first mac version, based partly on Atari software by Lars Jansen.
  50.     05-09-95    FWC        cleaned up, translated comments into english, Eli Brenner suggested a better way to do the
  51.                         character to float conversion
  52.     21-02-97    fwc        new code, system 7.5 compatible based partly on code from Inside Macintosh
  53.                         (and after suggestions from Hiro Akutsu). The code first checks if there's a
  54.                         message available, so it no longer hogs the computer. Support for sending measurements
  55.                         requests added.
  56.     26-02-97    fwc        removed the SLOW parameter as it wasn't really necessary to use this. Changed the
  57.                         strings that returned driver names.
  58.  
  59. ************************************************************************ */
  60.  
  61.  
  62.  
  63. #include     "luminanceMeter.h"
  64.  
  65. //  driver reference numbers
  66. short int   gOutputRefNum;                 //  output driver reference number    
  67. short int    gInputRefNum;                 //  input driver reference number
  68.  
  69. // strings used by the routines below
  70.  
  71. unsigned char    *serialDriverString[][2] = { "\p.AOut", "\p.AIn", "\p.BOut", "\p.BIn" };
  72. char            *portNameString[]          = { "ModemPort", "PrinterPort" };
  73.  
  74.  
  75.  
  76. int initLuminanceMeter( portType port )
  77. {
  78.     if( openSerialDriver( port ) )
  79.     {
  80.         if( setHandshakeOptions() )
  81.             if( configureSerialPort() )
  82.             {
  83.                 setDTR(HIGH);        // setDTR high all the time
  84.                 return( true );
  85.             }
  86.         serialDriverStatusCheck();
  87.         closeSerialDriver();
  88.     }
  89.     printf( "\n initLuminanceMeter(): error: could not open serial driver or port." );
  90.     return( false );
  91. }
  92.  
  93. int getLuminance( double *lum, char *message )
  94. {
  95.     ParamBlockRec    par;
  96.     char            buffer[ MESSAGE_LENGTH ];
  97.     double            time;
  98.     OSErr            error;
  99.     
  100.     // init parameterBlock
  101.     
  102.     par.ioParam.ioRefNum         = gInputRefNum;        // input driver number
  103.     par.ioParam.ioBuffer         = buffer;            // buffer address
  104.     par.ioParam.ioReqCount         = MESSAGE_LENGTH;    // no count yet
  105.     par.ioParam.ioCompletion     = NULL;
  106.     par.ioParam.ioVRefNum        = 0;
  107.     par.ioParam.ioPosMode        = 0;
  108.     
  109.     if( clearSerialBuffer() )
  110.     {    
  111.         sendMeasurementRequest();        
  112.         // if there is no message, PBReadSync() below waits indefinetely
  113.         // so we first check whether there is an appropriately sized message
  114.         if( !checkMeasurementPresent( &time ) )
  115.         {
  116.             sprintf( message, "No response from luminance meter after %2.2f secs", time );
  117.             *lum = -1.0;
  118.             return( false );        
  119.         }
  120.         else
  121.         {    
  122.             // when a complete message is available, read it    
  123.             error = PBReadSync( &par );    // if there is no message, this function would wait indefinetely
  124.             if( error != noErr )
  125.             {
  126.                 printf( "\n getLuminance(): error reading input serial buffer" );
  127.                 serialDriverStatusCheck( );
  128.                 return( false );
  129.             }
  130.         }
  131.     }
  132.     else
  133.         return( false );
  134.         
  135.     buffer[10]=0;        // replace character return by 0
  136.     *lum = atof( &buffer[4] );    
  137.     sprintf( message, "Mode: %c, Unit: %c, Calibration: %c, Measurement: %c", buffer[0], buffer[1], buffer[2], buffer[3] );
  138.  
  139.     return( true );
  140. }
  141.  
  142. char *returnPortName( portType port )
  143. {
  144.     return( portNameString[ port ] );
  145. }
  146.  
  147.  
  148. int checkMeasurementPresent( double *t )
  149. {
  150.     int             wait = true;
  151.     clock_t     start;
  152.     
  153.     start = clock();
  154.     while( checkSerialBuffer() < MESSAGE_LENGTH && wait )              // wait while there is no complete message yet
  155.         if( ( *t = ( clock() - start) / 60.0 ) > PATIENCE ) wait = false;
  156.     return( wait );
  157. }
  158.  
  159. // the minolta manual specifies that setting the request signal to low is the way to get a
  160. // measurement going. I've tried to increase the signal followed (within ~1 sec by a decrease,
  161. // couldn't get the thing to output any data. I now set the signal high when initialising the
  162. // driver and meter, and only briefly (~0.1 s) decrease the signal. This is sufficient to get a
  163. // measurement.
  164.  
  165. int sendMeasurementRequest( void )
  166. {
  167.     OSErr         error;
  168.     clock_t        start;
  169.     
  170.     error = Control(gOutputRefNum, LOW, NULL );
  171.  
  172.     if( error != noErr )
  173.     {
  174.         printf( "\n sendMeasurementRequest(): error setting DTR LOW" );
  175.         return( false );
  176.     }        
  177.     
  178.     start = clock();
  179.     while( ( ( clock() - start) / 60.0 ) < REQUEST_LOW_TIME ) ;
  180.     
  181.     error = Control(gOutputRefNum, HIGH, NULL );    
  182.     
  183.     if( error != noErr )
  184.     {
  185.         printf( "\n sendMeasurementRequest(): error setting DTR HIGH" );
  186.         return( false );
  187.     }        
  188.     return( true );
  189. }
  190.  
  191.  
  192. int checkSerialBuffer( void )
  193. {
  194.     OSErr     error;
  195.     long    count;
  196.     error = SerGetBuf( gOutputRefNum, &count );
  197.     if( error != noErr )
  198.     {
  199.         printf( "\n checkSerialBuffer(): error checking output serial buffer count (%d)", count );
  200.         return( false );
  201.     }        
  202.     return( (int) count );    
  203. }
  204.  
  205.  
  206. int setDTR( dtrType dtr )
  207. {
  208.     OSErr error;
  209.     error = Control(gOutputRefNum, dtr, NULL );  // set DTR high or low (+5V or -5V at DTR pin) 
  210.     if( error != noErr )
  211.     {
  212.         printf( "\n setDTR(): error setting DTR %s", dtr==HIGH?"high":"low" );
  213.         return( false );
  214.     }        
  215.     return( true );
  216. }
  217.  
  218.  
  219. int setHandshakeOptions( void )
  220. {
  221.         // Set flow control method and other options. Note that you only need to set
  222.         // the output driver; the settings are reflected on the input side.
  223.     OSErr     error;    
  224.     SerShk     serShkRec;                 // serial handshake record
  225.  
  226.     serShkRec.fXOn = 0;                // 0 {turn off XON/XOFF output flow control}    
  227.     serShkRec.fCTS = 1;               // 1 = to do hardware control, we'll be using the DTR line to control the photometer trigger (+5V and -5V). */
  228.     serShkRec.xOn  = 0;  
  229.     serShkRec.xOff = 0; 
  230.     serShkRec.errs = 0;                // clear error mask    
  231.     serShkRec.evts = 0;                // clear event mask    
  232.     serShkRec.fInX = 0;                // 1 = turn on XON/XOFF input flow control
  233.     serShkRec.fDTR = 1;                // set to 0 to turn off DTR input flow control
  234.     
  235.     error = Control(gOutputRefNum, 14, &serShkRec);    // this is the serHandShake call that allows one to set DTR control
  236.     if( error != noErr )
  237.     {
  238.         printf( "\n setHandshakeOptions(): error setting handshake options" );
  239.         return( false );
  240.     }        
  241.     return( true );
  242. }
  243.  
  244.  
  245. int clearSerialBuffer( void )
  246. {
  247.     OSErr error;
  248.     error = KillIO( gOutputRefNum );
  249.     if( error != noErr )
  250.     {
  251.         printf( "\n clearSerialBuffer(): error clearing output serial buffer" );
  252.         return( false );
  253.     }
  254.     // although Inside Mac specifies that it is not necessary to kill the IO for the input
  255.     // buffer, I had the impression it occasionally worked better when I did it anyway.
  256.     error = KillIO( gInputRefNum );
  257.     if( error != noErr )
  258.     {
  259.         printf( "\n clearSerialBuffer(): error clearing input serial buffer" );
  260.         return( false );
  261.     }        
  262.     return( true );    
  263. }
  264.  
  265.  
  266. int configureSerialPort( void )
  267. {
  268.     int     configParam;
  269.     OSErr    error;
  270.     configParam = baud4800 + data7 + stop20 + evenParity; // constants defined in "serial.h"
  271.     error = SerReset( gOutputRefNum, configParam );
  272.     if( error != noErr )
  273.     {
  274.         printf( "\n configureSerialPort(): error configuring output port" );
  275.         return( false );
  276.     }        
  277.     return( true );
  278. }
  279.  
  280.  
  281.  
  282. int openSerialDriver( portType port )
  283. {
  284.     // use the device mananger OpenDriver() function to open the drivers
  285.     
  286.     OSErr     error;
  287.     
  288.     error = OpenDriver( returnDriverString( port, OUTPUT ), &gOutputRefNum );    // always open output driver first
  289.  
  290.     if( error != noErr )
  291.     {
  292.         printf( "\n openSerialDriver(): error opening output driver" );
  293.         return( false );
  294.     }        
  295.     
  296.     error = OpenDriver( returnDriverString( port, INPUT ), &gInputRefNum );    // then open input driver
  297.     
  298.     if( error != noErr )
  299.     {
  300.         printf( "\n openSerialDriver(): error opening input driver" );
  301.         error = CloseDriver( gOutputRefNum );            // close output driver
  302.         return( false );
  303.     }        
  304.     
  305.     return( true );
  306. }
  307.  
  308.  
  309. int closeSerialDriver( void )
  310. {
  311.     OSErr     error;
  312.     error = KillIO( gOutputRefNum );            // terminate all pending I/O operations
  313.     if( error != noErr )
  314.     {
  315.         printf( "\n closeSerialDriver(): KillIO() error" );
  316.          return( false );
  317.     }
  318.     
  319.     error = CloseDriver(gInputRefNum);     //  close the input driver first
  320.     
  321.     if( error != noErr )
  322.     {
  323.         printf( "\n closeSerialDriver(): error closing input driver" );
  324.         return( false );
  325.     }
  326.     
  327.     error = CloseDriver(gOutputRefNum);     //  then close the output driver
  328.     if( error != noErr )
  329.     {
  330.         printf( "\n closeSerialDriver(): error closing output driver" );
  331.         return( false );
  332.     }
  333.     return( true );
  334. }
  335.  
  336.  
  337.  
  338.  
  339. int serialDriverStatusCheck( void )
  340. {
  341.         // to check the Serial Driver status. see.7-25 in the Inside-Macintosh
  342.     SerStaRec     status;
  343.     int breakErr = 8;
  344.     OSErr    error;
  345.         
  346.     error = SerStatus(gInputRefNum,&status);
  347.  
  348.     if( error || status.cumErrs)
  349.           printf("\n Serial Driver status check: OSErr %d, cumErrs %d, rdPend %d, ctsHold %d,  xOffHold %d --- ",
  350.                   error, status.cumErrs, status.rdPend, status.ctsHold, status.xOffHold );
  351.     else 
  352.         printf("\n Serial Driver status check: no errors");
  353.     if(status.cumErrs & swOverrunErr)     printf("\n software overrun error.\n");
  354.     if(status.cumErrs & breakErr)         printf("\n break signal asserted.\n");
  355.     if(status.cumErrs & parityErr)         printf("\n parity error.\n");
  356.     if(status.cumErrs & hwOverrunErr)     printf("\n hardware overrun error.\n");
  357.     if(status.cumErrs & framingErr)     printf("\n framing error.\n");
  358.      if(status.cumErrs & swOverrunErr)     printf("\n software overrun error.\n"); 
  359.  
  360.     return( status.cumErrs );    
  361. }
  362.